import sys
import os
import traceback
from threading import Lock

class Singleton(object):
    _mutex = Lock()
    _instance = None
    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._mutex.acquire()
            if cls._instance is None:
                cls._instance = super(Singleton, cls).__new__(cls)
            cls._mutex.release()
        return cls._instance

def byteify(data, ignore_dicts = False):
    """
    json loads function object hook, used to encode string to a dict
    object without utf8 format
    :param data:
    :param ignore_dicts:
    :return:
    """
    # if this is a unicode string, return its string representation
    if isinstance(data, unicode):
        return data.encode('utf-8')
    # if this is a list of values, return list of byteified values
    if isinstance(data, list):
        return [ byteify(item, ignore_dicts=True) for item in data ]
    # if this is a dictionary, return dictionary of byteified keys and values
    # but only if we haven't already byteified it
    if isinstance(data, dict) and not ignore_dicts:
        return {
            byteify(key, ignore_dicts=True): byteify(value, ignore_dicts=True)
            for key, value in data.iteritems()
        }
    # if it's anything else, return it in its original form
    return data
